package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.uqbike.object.pojo.Account;
import com.tbit.uqbike.object.pojo.AccountUser;
import com.tbit.uqbike.object.pojo.BatteryOperationCount;
import com.tbit.uqbike.object.pojo.vo.BatteryLogCountVO;
import com.tbit.uqbike.object.pojo.vo.BatteryLogVO;
import com.tbit.uqbike.object.pojo.vo.BatteryOperationCountVO;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.service.business.BatteryLogService;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import com.tbit.uqbike.webmanager.dao.core.AccountUserDao;
import com.tbit.uqbike.webmanager.dao.log.BatteryLogDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 电池操作日志接口实现类
 *
 * @Author:BUGTian
 * @DATE: 2022/5/12
 */
@Service
public class BatteryLogServiceImpl implements BatteryLogService {

    @Autowired
    private BatteryLogDao batteryLogDao;

    @Autowired
    private AccountUserDao accountUserDao;

    @Resource
    private AccountDao accountDao;

    @Override
    public PageResult<BatteryLogVO> queryPage(Integer page, Integer size, Integer accountId, Date startTime, Date endTime, Integer accountUserId, String batteryNO) {
        return getBatteryLogVOPageResult(page, size, accountId, startTime, endTime, accountUserId, batteryNO, null);
    }

    /**
     * 公共方法抽取
     *
     * @param page          当前页码
     * @param size          每页显示的行
     * @param accountId     品牌id
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param batteryNO     电池编号
     * @param accountUserId 操作用户id
     * @return
     */
    private PageResult<BatteryLogVO> getBatteryLogVOPageResult(Integer page, Integer size, Integer accountId, Date startTime, Date endTime, Integer accountUserId, String batteryNO, Integer type) {
        //分页查询电池操作记录
        PageInfo<BatteryLogVO> pageInfo = PageHelper.startPage(page, size).doSelectPageInfo(() -> batteryLogDao.query(accountId, startTime, endTime, accountUserId, batteryNO, type));
        //获取区域内运维人员map
        Map<Integer, AccountUser> accountUserMap = getAccountMap(accountId);
        //获取区域名称
        Account account = accountDao.getByAccountId(accountId);
        List<BatteryLogVO> list = pageInfo.getList();
        //运维人员姓名和手机号赋值
        for (BatteryLogVO batteryLogVO : list) {
            Integer id = batteryLogVO.getAccountUserId();
            AccountUser accountUser = accountUserMap.get(id);
            batteryLogVO.setAccountUserName(accountUser == null ? "" : accountUser.getName());
            batteryLogVO.setAccountUserPhone(accountUser == null ? "" : accountUser.getPhone());
            batteryLogVO.setTypeExplain(explainType(batteryLogVO.getType()));
            batteryLogVO.setAccountName(account.getName());
        }
        return new PageResult<>(page, size, pageInfo.getTotal(), pageInfo.getPages(), list);
    }

    @Override
    public List<BatteryOperationCountVO> queryBatteryOperationCount(Integer accountId, Date startTime, Date endTime, Integer accountUserId) {
        List<BatteryOperationCountVO> batteryOperationCountVOList = new ArrayList<>();
        //电池操作数量统计(按日、类型分组)
        List<BatteryOperationCount> list = batteryLogDao.queryBatteryOperationCount(accountId, startTime, endTime, accountUserId);
        Map<String, Integer> map = new HashMap<>();
        for (BatteryOperationCount batteryOperationCount : list) {
            map.put(batteryOperationCount.getTime() + "_" + batteryOperationCount.getType(), batteryOperationCount.getCount());
        }
        //获取时间区间的每一天
        long betweenDay = DateUtil.between(startTime, endTime, DateUnit.DAY);
        for (long i = 0; i < betweenDay + 1; i++) {
            String date = DateUtil.formatDate(DateUtil.offsetDay(startTime, (int) i));
            BatteryOperationCountVO batteryOperationCountVO = compute(date, map);
            batteryOperationCountVOList.add(batteryOperationCountVO);
        }
        return batteryOperationCountVOList;
    }
    @Override
    public PageResult<BatteryLogVO> queryDetails(Integer page, Integer size, Integer accountId, Date startTime, Date endTime, Integer accountUserId, Integer type) {
        return getBatteryLogVOPageResult(page, size, accountId, startTime, endTime, accountUserId, null, type);
    }

    @Override
    public PageResult<BatteryLogCountVO> queryOverview(Integer page, Integer size, Integer accountId, Date startTime, Date endTime, Integer accountUserId) {
        //电池出入库总览(根据操作类型、人员id分组)
        PageInfo<BatteryLogCountVO> pageInfo = PageHelper.startPage(page, size).doSelectPageInfo(() -> batteryLogDao.queryOverview(accountId, startTime, endTime, accountUserId));
        List<BatteryLogCountVO> list = pageInfo.getList();
        //获取区域内运维人员map
        Map<Integer, AccountUser> accountUserMap = getAccountMap(accountId);
        for (BatteryLogCountVO batteryLogCountVO : list) {
            Integer id = batteryLogCountVO.getAccountUserId();
            AccountUser accountUser = accountUserMap.get(id);
            batteryLogCountVO.setAccountUserName(accountUser == null ? "" : accountUser.getName());
            batteryLogCountVO.setAccountUserPhone(accountUser == null ? "" : accountUser.getPhone());
        }
        return new PageResult<>(page, size, pageInfo.getTotal(), pageInfo.getPages(), list);
    }

    @Override
    public void insert(Integer accountId, Integer batteryId, String batteryNO, Integer type, Integer accountUserId, Date addTime, String remark) {
        batteryLogDao.insert(accountId, batteryId, batteryNO, type, accountUserId, addTime, remark);
    }

    /**
     * 获取区域内运维人员map
     *
     * @param accountId 区域id
     * @return
     */
    private Map<Integer, AccountUser> getAccountMap(Integer accountId) {
        Map<Integer, AccountUser> accountUserMap = new HashMap<>();
        //获取区域内所有的运维人员
        List<AccountUser> accountUserList = accountUserDao.getByType(accountId, false);
        if (accountUserList != null && accountUserList.size() > 0) {
            accountUserList.forEach(accountUser -> accountUserMap.put(accountUser.getAccountUserId(), accountUser));
        }
        return accountUserMap;
    }

    /**
     * 操作类型解析
     *
     * @param type 操作类型type
     * @return 解析
     */
    public String explainType(Integer type) {
        switch (type) {
            case 1:
                return "待出库";
            case 2:
                return "删除待入库";
            case 3:
                return "领取";
            case 4:
                return "归还";
            case 5:
                return "入库";
            case 6:
                return "绑定电池";
            case 7:
                return "解绑电池";
            case 8:
                return "上报丢失";
            case 9:
                return "上报寻回";
            case 10:
                return "添加电池";
            case 11:
                return "移除电池";
            default:
                return "未知";
        }
    }


    /**
     * 计算当天各操作类型数量
     */
    private BatteryOperationCountVO compute(String date, Map<String, Integer> map) {
        BatteryOperationCountVO batteryOperationCountVO = new BatteryOperationCountVO();
        //待出库数量
        Integer waitOutCount = map.get(date + "_1");
        //删除待入库数量
        Integer deleteWaitInCount = map.get(date + "_2");
        //领取数量
        Integer receiveCount = map.get(date + "_3");
        //归还数量
        Integer returnCount = map.get(date + "_4");
        //入库数量
        Integer inCount = map.get(date + "_5");
        batteryOperationCountVO
                .setTime(date)
                .setWaitOutCount(waitOutCount == null ? 0 : waitOutCount)
                .setDeleteWaitInCount(deleteWaitInCount == null ? 0 : deleteWaitInCount)
                .setReceiveCount(receiveCount == null ? 0 : receiveCount)
                .setReturnCount(returnCount == null ? 0 : returnCount)
                .setInCount(inCount == null ? 0 : inCount);
        return batteryOperationCountVO;
    }
}
